﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InstaMe.utils
{
    public class TimeUtils
    {
        private const long BASE_TICK_TIME = 621355968000000000; // DateTime(1970, 1, 1, 0, 0, 0);
        private static DateTime BASE_DATE_TIME = new DateTime(1970, 1, 1, 0, 0, 0).ToLocalTime();
        private const long SECOND_LIMIT = 10000000000;
        private const long ONE_DAY_SECOND = 86400; // 60 * 60 * 24;
        private const long SEVEN_DAY_SECOND = 604800; // 60 * 60 * 24 * 7;
        private const long ONE_HOUR_SECOND = 3600;//60 * 60
        private const long FIVE_MINUTES_SECOND = 300;//5 * 60
        private const long ONE_MINUTES_SECOND = 60;

        public static long toMilisecond(long aSecondTime)
        {
            if (aSecondTime > SECOND_LIMIT)
            {
                return aSecondTime;
            }
            else
            {
                return aSecondTime * 1000;
            }
        }

        public static long toSecond(long aMilisecondTime)
        {
            if (aMilisecondTime > SECOND_LIMIT)
            {
                return aMilisecondTime / 1000;
            }
            else
            {
                return aMilisecondTime;
            }
        }

        public static long currentTimeMilis() // 10000 ns
        {
            return (DateTime.UtcNow.Ticks - BASE_TICK_TIME) / 10000;
        }

        public static long currentTimeSecond()
        {
            return currentTimeMilis() / 1000;
        }

        public static string currentTimeToString(string aFormat)
        {
            return DateTime.Now.ToString(aFormat);
        }

        // Custom DateTime Format
        // http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
        public static string timeToString(long aTimeMilis, string aFormat)  // 0 ns ??
        {
            DateTime iDateTime = BASE_DATE_TIME.AddMilliseconds(toMilisecond(aTimeMilis));            

            return iDateTime.ToString(aFormat);
        }

        // Custom TimeSpan Format
        // http://msdn.microsoft.com/en-us/library/ee372287.aspx
        public static string timeSpanToString(long aTimeMilis, string aFormat)  // 0 ns ??
        {
            TimeSpan iTimeSpan = TimeSpan.FromMilliseconds(aTimeMilis);           
            return iTimeSpan.ToString(aFormat);
        }

        public static int getYearDistanceFromNow(long aTimeMilis)
        {
            //server return dob with origin is 1/1/1970
            // j2me way
            var iPivotYear = new DateTime(1970, 1, 1);
            int diffDays = DateTime.Now.Subtract(iPivotYear.AddMilliseconds(toMilisecond(aTimeMilis))).Days;
            return (diffDays + 364)/365;
            //accurate way:
//            var bday = new DateTime(1970, 1, 1).AddMilliseconds(toMilisecond(aTimeMilis));
//            Logger.LogDebug("bday:"+bday.Day+"-"+bday.Month+"-"+bday.Year);
//            DateTime now = DateTime.Today;
//            int age = now.Year - bday.Year + 1;
//            if (now < bday.AddYears(age)) age--;
//            return age;
        }

        //public static long toServerTimeSecond(long aLocalTime)
        //{
        //    long iSecondTime = toSecond(aLocalTime);
        //    return iSecondTime - (CoreSetting.CLIENT_LOGIN_TIMESTAMP - CoreSetting.SERVER_LOGIN_TIMESTAMP);
        //}

        //public static long toServerTimeMilis(long aLocalTime)
        //{
        //    long iMilisecondsTime = toMilisecond(aLocalTime);
        //    return iMilisecondsTime - (CoreSetting.CLIENT_LOGIN_TIMESTAMP - CoreSetting.SERVER_LOGIN_TIMESTAMP) * 1000;
        //}

        //public static string ToChatSeparatorTime(long aTime)
        //{
        //    long iCurrentServerSecond = toServerTimeSecond(currentTimeSecond());
        //    DateTime iCurrentServerDateTime = BASE_DATE_TIME.AddSeconds(iCurrentServerSecond);
        //    DateTime iChatServerDateTime = BASE_DATE_TIME.AddSeconds(toSecond(aTime));

        //    long iSecondFromNewDay = (long)iCurrentServerDateTime.TimeOfDay.TotalSeconds;

        //    TimeSpan iDistance = iCurrentServerDateTime.Subtract(iChatServerDateTime);

        //    long iTotalSecond = (long)iDistance.TotalSeconds;

        //    if (iTotalSecond < 0)
        //    { 
        //        if (iTotalSecond > (iSecondFromNewDay - ONE_DAY_SECOND)) // still in day
        //        {
        //            return iChatServerDateTime.ToString("HH:mm");
        //        }
        //        else { // diff day
        //            return iChatServerDateTime.ToString("dd/MM/yyyy");
        //        }
        //    }
        //    else if (iTotalSecond <= iSecondFromNewDay)
        //    {
        //        return iChatServerDateTime.ToString("HH:mm");
        //    }
        //    else if ((iTotalSecond - iSecondFromNewDay) <= SEVEN_DAY_SECOND)
        //    {
        //        long totalSecond = iTotalSecond - iSecondFromNewDay;
        //        long day = totalSecond / ONE_DAY_SECOND;
        //        if (totalSecond % ONE_DAY_SECOND != 0)
        //        {
        //            day++;
        //        }
        //        return day + " ngày";
        //    }
        //    else
        //    {
        //        return iChatServerDateTime.ToString("dd/MM/yyyy");
        //    }
        //}

        //public static string ToMessageTime(long aTime)
        //{
        //    long iCurrentServerSecond = toServerTimeSecond(currentTimeSecond());
        //    DateTime iCurrentServerDateTime = BASE_DATE_TIME.AddSeconds(iCurrentServerSecond);
        //    DateTime iChatServerDateTime = BASE_DATE_TIME.AddSeconds(toSecond(aTime));

        //    long iSecondFromNewDay = (long)iCurrentServerDateTime.TimeOfDay.TotalSeconds;

        //    TimeSpan iDistance = iCurrentServerDateTime.Subtract(iChatServerDateTime);

        //    long iTotalSecond = (long)iDistance.TotalSeconds;

        //    if (iTotalSecond < 0)
        //    {
        //        if (iTotalSecond > (iSecondFromNewDay - ONE_DAY_SECOND)) // still in day
        //        {
        //            return iChatServerDateTime.ToString("HH:mm");
        //        }
        //        else
        //        { // diff day
        //            return iChatServerDateTime.ToString("dd/MM/yyyy");
        //        }
        //    }
        //    else if (iTotalSecond <= iSecondFromNewDay)
        //    {
        //        return iChatServerDateTime.ToString("HH:mm");
        //    }
        //    else if ((iTotalSecond - iSecondFromNewDay) <= ONE_DAY_SECOND)
        //    {
        //        return "Yesterday " + iChatServerDateTime.ToString("HH:mm");
        //    }
        //    else if ((iTotalSecond - iSecondFromNewDay) <= SEVEN_DAY_SECOND)
        //    {
        //        return iChatServerDateTime.ToString("ddd HH:mm");
        //    }
        //    else
        //    {
        //        return iChatServerDateTime.ToString("MMM dd, yyyy HH:mm");
        //    }
        //}

        public static bool isDiffDay(long aTime, long aOtherTime)
        {            
            DateTime iTimeServerDateTime = BASE_DATE_TIME.AddSeconds(toSecond(aTime));
            DateTime iOtherTimeServerDateTime = BASE_DATE_TIME.AddSeconds(toSecond(aOtherTime));

            if (iTimeServerDateTime.Month == iOtherTimeServerDateTime.Month 
                && iTimeServerDateTime.Day == iOtherTimeServerDateTime.Day)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public static string ToChatTime(long aTime, string aFormat)
        {
            DateTime iChatServerDateTime = BASE_DATE_TIME.AddSeconds(toSecond(aTime));
            return iChatServerDateTime.ToString(aFormat);
        }

        public static DateTime TimeStampToDateTime(long aTime)
        {
            return BASE_DATE_TIME.AddSeconds(toSecond(aTime));
        }

        public static long DateTimeToTimeStamp(DateTime aTime)
        {
            try
            {
                return toSecond((long) aTime.Subtract(BASE_DATE_TIME).TotalSeconds);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                
            }
            return 0L;
        }

        //public static string convertLastOnlineTime(long lastOnline) {
        //    if (lastOnline < 1) {
        //        return "";
        //    }
        //    long serverTime = toServerTimeSecond(currentTimeSecond());
        //    long delta = serverTime - lastOnline;
        //    if (delta < FIVE_MINUTES_SECOND) {
        //        return AppResources.IS_ONLINE;
        //    } else if (delta < ONE_HOUR_SECOND) {
        //        return AppResources.ONLINE_AT_ + delta / ONE_MINUTES_SECOND + AppResources._MINUTE_BEFORE;
        //    } else if (delta < ONE_DAY_SECOND) {
        //        return AppResources.ONLINE_AT_ + delta / ONE_HOUR_SECOND + AppResources._HOUR_BEFORE;
        //    } else {
        //        return AppResources.ONLINE_AT_ + timeToString(lastOnline, "dd/MM/yyyy");
        //    }
        //}
    }
}
